﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace saolei
{
    public partial class Form1 : Form
    {
        //定义程序变量
        static int N = 10; //雷区格子的大小N*N
        static int M = 10; //雷的个数

        //定义存放N*N个按钮对象的数组
        List<Button> btns = new List<Button>();

        //定义存放M个雷所在按钮位置的数组
        int[] leiPos = new int[M];
        private bool gameOver;

        //定义存放每个按钮是否翻转的状态数组
        int[] status = new int[N * N];//0-没翻转，1-翻转

        //定义计时器的变
        int totoltime = 2 * 60;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        //开始按钮的事件处理
        private void button1_Click(object sender, EventArgs e)
        {
            //启动计时器
            timer1.Enabled = true;
            //动态生成N*N个按钮放置在屏幕上
            for (int i = 0; i < N; i++)
                for (int j = 0; j < N; j++)
                {
                    //1.创建一个Button对象
                    Button obj = new Button();
                    //2.设置相关属性：位置，大小，宽度
                    obj.Width = 40;
                    obj.Height = 40;
                    obj.Location = new Point(40 * j + 60, 40 * i + 80);//坐标位置
                    //3.将按钮对象放置屏幕上——加入到当前窗口的Controls中
                    this.Controls.Add(obj);
                    //4.将按钮对象加入到数组btns中进行保存
                    btns.Add(obj);
                    //设置按钮对象被点击后，调用的处理方法
                    obj.Click += new System.EventHandler(ButtonClickHandler);
                }//end for
            //随机产生M个雷的位置
            Random rd = new Random();//创建一个随机数产生器对象
            for (int i = 0; i < M; i++)
            {
                int x = rd.Next(N * N);//随机产生一个【0，N*N-1】的数
                //判断x的值在前面【0，i-1】次是否已经出现过
                bool flag = false;//没有出现的标志
                for (int j = 0; j < i; j++)
                {
                    if (leiPos[j] == x)
                    {
                        flag = true; break;
                    }
                }
                if (flag == false)//判断flag的值
                    leiPos[i] = x;
                else
                    i--;//！！！
            }
            //DispLei();//调用显示雷的分布
            button1.Enabled = false;//将开始按钮设置为失效
        }//end button1_Click

        //定义显示雷分布的方法DispLei
        private void DispLei()
        {
            //遍历存放雷位置的数组
            for (int i = 0; i < M; i++)
            {
                int x = leiPos[i];//取第i个雷所在的位置
                //设置该位置上按钮为红色
                btns[x].BackColor = Color.Beige;
            }
        }//end DispLei

        //定义用户点击按钮时的处理方法
        private void ButtonClickHandler(object sender, EventArgs e)
        {
            //判断游戏是否结束
            if (gameOver == true) return;
            //找出本次被点击的按钮的位置序号
            Button current = (Button)sender;
            for (int i = 0; i < N * N; i++)
            {
                if (btns[i] == current)//第i个位置被点击{
                    //判断该位置是否有雷
                    //判断i是否在前面生成的雷的位置数组中
                    if (leiPos.Contains(i))
                    {
                        //有雷
                        gameOver = true;//设置游戏结束
                        timer1.Enabled = false;
                        again.Enabled = true;//再来一局
                        MessageBox.Show("哈哈，你被炸死了！");
                        DispLei();//显示雷的分布，让玩家死得瞑目
                    }
                    else
                    {   //没有雷，位置翻转，设置不同的背景颜色，白色
                        current.BackColor = Color.White;
                        //进一步扫描周围8个方向位置雷的情况
                        doScannGroud(i);
                        //将该位置的状态设置为已翻转
                        status[i] = 1;
                        //判断是否通关
                        doCheckWinner();
                    }
            }   //end if
        }//ButtonClickHandler
        //定义独立的方法：周围雷的情况
        private void doScannGroud(int i)
        {
            //判断位置i之前是否已经被翻转

            int count = 0;//存放周围雷的个数
            //1.判断上方位置是否有雷
            if (i >=N)
            {
                if (leiPos.Contains(i - N)) count++;
            }
            //2.判断下方位置是否有雷
            if (i<N*(N-1))
            {
                if (leiPos.Contains(i + N)) count++;
            }
            //3.判断左方位置是否有雷
            if (i%10 >0)
            {
                if (leiPos.Contains(i - 1)) count++;
            }
            //4.判断右方位置是否有雷
            if (i % 10<N-1)
            {
                if (leiPos.Contains(i + 1)) count++;
            }
            //5.判断左上方位置是否有雷
            if (i >=N&& i % 10 > 0)
            {
                if (leiPos.Contains(i - N-1)) count++;
            }
            //6.判断左下方位置是否有雷
            if (i < N * (N - 1) && i % 10 > 0)
            {
                if (leiPos.Contains(i + N - 1)) count++;
            }
            //7.判断右上方位置是否有雷
            if (i >= N && i % 10 < N - 1)
            {
                if (leiPos.Contains(i - N + 1)) count++;
            }
            //8.判断右下方位置是否有雷
            if (i < N * (N - 1) && i % 10 < N - 1)
            {
                if (leiPos.Contains(i + N + 1)) count++;
            }
            if (count > 0) //周围有雷，显示雷的个数
                btns[i].Text = "" + count;
            else //周围没有雷
            {
                //将周围按钮进行翻转
                doOpenGroud(i);
            }
        }

        //定义将i位置周围的位置进行翻转的方法
        private void doOpenGroud(int i)
        {
            //翻转上方位置
            if (i - N >= 0&&status[i - N] ==0) { 
                btns[i - N].BackColor = Color.White;
                status[i - N] = 1;
                doScannGroud(i - N);
            }
            //翻转下方
            if (i /N < N - 1 && status[i + N] == 0) { 
                btns[i + N].BackColor = Color.White;
                status[i + N] = 1;
                doScannGroud(i + N);
            }
            //翻转左方
            if (i % N > 0 && status[i - 1] == 0) {
                btns[i -1].BackColor = Color.White;
                status[i - 1] = 1;
                doScannGroud(i - 1);
            }
                
            //翻转右方
            if (i % N < N - 1 && status[i +1] == 0) {
                btns[i + 1].BackColor = Color.White;
                status[i + 1] = 1;
                doScannGroud(i + 1);
            }
                
            //翻转左上方位置
            if (i - N >= 0 && i % N > 0 && status[i - N - 1] == 0) {
                btns[i - N - 1].BackColor = Color.White;
                status[i - N - 1] = 1;
                doScannGroud(i - N - 1);
            }
                
            //翻转左下方位置
            if (i / N < N - 1 && i % N > 0 && status[i + N - 1] == 0) {
                btns[i + N - 1].BackColor = Color.White;
                status[i + N - 1] = 1;
                doScannGroud(i+ N - 1);
            }
                
            //翻转右上方位置
            if (i - N >= 0 && i % N < N - 1 && status[i - N + 1] == 0) {
                btns[i - N + 1].BackColor = Color.White;
                status[i - N + 1] = 1;
                doScannGroud(i - N + 1);
            }
                
            //翻转右下方位置
            if (i / N < N - 1 && i % N < N - 1 && status[i + N + 1] == 0) {
                btns[i + N + 1].BackColor = Color.White;
                status[i + N + 1] = 1;
                doScannGroud(i + N + 1);
            }
                
        }

        //进行游戏是否过关的检验
        private void doCheckWinner()
        {
            //判断屏幕上，被翻转的按钮的个数是否是N*N-M个
            int count = 0;//定义被翻转按钮的个数
            for(int i=0;i<N*N;i++)
            {
                if (btns[i].BackColor == Color.White) count++;
            }
            if(count==N*N-M)
            {
                gameOver = true;//设置游戏结束标志
                timer1.Enabled = false;
                again.Enabled = true;//再来一局
                MessageBox.Show("WWW,恭喜通过");
   
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            totoltime--;
            label1.Text = "时间还有：" + totoltime;
            if(totoltime==0)
            {
                timer1.Enabled = false;//停止计时器
                gameOver = true;
                MessageBox.Show("游戏时间已到！");
            }
        }
        //再来一局的按钮事件处理
        private void again_Click(object sender, EventArgs e)
        {
            doPlayAgain();
        }
        private void doPlayAgain()
        {
            //1.将所有按钮的颜色设置为初始化颜色
            for(int i = 0; i < N * N; i++) { 
                btns[i].BackColor = Control.DefaultBackColor;
                btns[i].Text = "";//清楚按钮上的文字提示

            }
            //2.设置status的值为0——没有翻转
            for (int i = 0; i < N * N; i++)
                status[i] = 0;
            //3.重新安排雷的位置
            for (int i = 0; i < M; i++)
                leiPos[i] = -1;
            Random rd = new Random();
            for (int i = 0; i < M; i++)
            {
                int x = rd.Next(N * N);
                if (leiPos.Contains(x) == false)
                    leiPos[i] = x;
                else i--;
            }
            //4.设置倒计时为初始值
            totoltime = 2 * 60;
            //5.启动倒计时
            timer1.Enabled = true;
            //6.设置游戏开始
            gameOver = false;
        }

        //设计统计按钮
        private void button2_Click(object sender, EventArgs e)
        {
            Form2 f = new Form2();//创建一个窗口对象
            f.Show();//显示该窗口
        }
    }

}
